package com.ry.est.service.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.ry.est.constants.Constants;
import com.ry.est.constants.ResultEnum;
import com.ry.est.dto.MaintainOrderDTO;
import com.ry.est.dto.PayOrderDTO;
import com.ry.est.exception.BussinessException;
import com.ry.est.service.MaintainOrderService;
import com.ry.est.service.PayOrderService;
import com.ry.est.service.PayService;
import com.ry.est.util.AliPayProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import sun.rmi.runtime.Log;

import java.util.Map;

/**
 * @author ry
 * @since 2021-11-16 11:07
 **/
@Service
public class ALiPayServiceImpl implements PayService {
    private static final Logger LOGGER = LoggerFactory.getLogger(ALiPayServiceImpl.class);

    @Autowired
    private MaintainOrderService maintainOrderService;

    @Autowired
    private PayOrderService payOrderService;

    @Autowired
    private AliPayProperties aliPayProperties;

    /**
     * 支付定金
     *
     * @param orderNo
     * @return
     * @throws Exception
     */
    @Override
    public String paySubscription(String orderNo) throws Exception {
        MaintainOrderDTO maintainOrderDTO = maintainOrderService.getByOrderNo(orderNo);
        //如果订单号不存在
        if (ObjectUtils.isEmpty(maintainOrderDTO)){
            throw new BussinessException(ResultEnum.FAIL_HAVE_NOT_EXIST);
        }

        //如果订单的定金已经支付
        Integer status = maintainOrderDTO.getStatus();
        if (ObjectUtils.nullSafeEquals(status, Constants.Order.MaintainStatus.PAY_DEPOSIT)){
            throw new BussinessException(ResultEnum.FAIL_PAY_DEPOSIT);
        }

        //创建支付订单
        String maintainOrderNo = maintainOrderDTO.getOrderNo();
        PayOrderDTO payOrderDTO = new PayOrderDTO();
        payOrderDTO.setOrderNo(maintainOrderNo);

        //一个维修单可能会发生多次支付，所以在每次支付的时候，生成不同的支付订单编号
        //支付订单编号 = 维修订单编号加5位随机数
        String payNo = generatePayNo(maintainOrderNo);
        payOrderDTO.setPayNo(payNo);
        payOrderDTO.setUserId(maintainOrderDTO.getUserId());
        //支付的是定金
        payOrderDTO.setPrice(maintainOrderDTO.getSubscription());
        payOrderDTO.setPayChannel(Constants.Order.Channel.ALIPAY);
        payOrderDTO.setCreatedUserId(maintainOrderDTO.getUserId());
        //1定金 2尾款
        payOrderDTO.setPayType(1);

        payOrderService. savePayOrder(payOrderDTO);

        //向支付宝发起支付的请求
        //alipayClient = new DefaultAlipayxx
        AlipayClient alipayClient = new DefaultAlipayClient(aliPayProperties.getGatewayUrl(),
                aliPayProperties.getAppId(),
                aliPayProperties.getMerchantPrivateKey(),
                "json",
                aliPayProperties.getCharset(),
                aliPayProperties.getAlipayPublicKey(),
                aliPayProperties.getSignType());
        //new AlipayTradePagePayRequest
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        //request.setReturnUrl
        request.setReturnUrl(aliPayProperties.getRedirectUrl());
        //request.setNotifyUrl
        request.setNotifyUrl(aliPayProperties.getNotifyUrl());
        JSONObject jsonObject = new JSONObject();
        jsonObject.accumulate("out_trade_no",payNo);
        jsonObject.accumulate("total_amount",payOrderDTO.getPrice().toString());
        jsonObject.accumulate("subject","华为mate10-维修定金");
        jsonObject.accumulate("body","");
        jsonObject.accumulate("product_code","FAST_INSTANT_TRADE_PAY");
        //request.setBizContent(jsonObject.toString())
        request.setBizContent(jsonObject.toString());

        //result = alipayClient.pageExecute(request);
        String result = alipayClient.pageExecute(request).getBody();
        LOGGER.debug("支付信息");
        return result;
    }

    /**
     * 对支付宝异步回调的处理
     *
     * @param params
     * @return
     */
    @Override
    public String aliPayNotify(Map<String, String> params) throws AlipayApiException {
        //验证签名
        boolean signVerified = isSignVerified(params);

        //签名不正确
        if (!signVerified){
            return "fail";
        }

        //签名正确
        //获取订单支付号
        String payNo = params.get("out_trade_no");
        //根据支付号查询订单
        PayOrderDTO payOrderDTO = payOrderService.getByPayNo(payNo);
        //只要不是未支付的状态，就不做处理
        if (!ObjectUtils.nullSafeEquals(payOrderDTO.getStatus(),Constants.Order.PayStatus.UN_PAY)){
            return "success";
        }
        //修改订单状态
        String trade_no = params.get("trade_no");
        payOrderService.updateOrderStatusToSuccess(payOrderDTO.getId(),trade_no);
        //修改维修订单的状态为已支付定金
        maintainOrderService.updateOrderStatusToPayed(payOrderDTO.getOrderNo());

        //修改维修订单的状态为已支付定金，添加维修订单状态


        return "success";
    }

    public boolean isSignVerified(Map<String, String> params) throws AlipayApiException {
        return AlipaySignature.rsaCheckV1(params,
                    aliPayProperties.getAlipayPublicKey(),
                    aliPayProperties.getCharset(),
                    aliPayProperties.getSignType());
    }

    private String generatePayNo(String maintainOrderNo) {
        return maintainOrderNo + RandomUtil.randomNumbers(5);
    }
}
